package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.AuditService;
import com.atguigu.tingshu.common.cache.GuiGuCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.atguigu.tingshu.common.constant.SystemConstant.*;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private AlbumAttributeValueMapper albumAttributeValueMapper;

	@Autowired
	private AlbumAttributeValueService albumAttributeValueService;

	@Autowired
	private AlbumStatMapper albumStatMapper;

	@Autowired
	private TrackInfoMapper trackInfoMapper;


	@Autowired
	private AuditService auditService;

	@Autowired
	private RabbitService rabbitService;





	@Override
	public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {

		//吧vo对象封装成po对象
		AlbumInfo albumInfo = BeanUtil.copyProperties(albumInfoVo, AlbumInfo.class);

		Long userId = AuthContextHolder.getUserId();
		albumInfo.setUserId(userId);
		albumInfo.setTracksForFree(3);
		albumInfo.setSecondsForFree(30);
		albumInfo.setStatus(SystemConstant.ALBUM_STATUS_NO_PASS);

		//保存专辑信息,mybatis框架保存数据后后会主键回显

		albumInfoMapper.insert(albumInfo);
		Long albumId = albumInfo.getId();

		//保存专辑标签信息,多对多的关系
		List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
		if (CollUtil.isNotEmpty(albumAttributeValueVoList)){

			List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueVoList
					.stream()
					.map(vo -> {
						AlbumAttributeValue albumAttributeValue = BeanUtil.copyProperties(vo, AlbumAttributeValue.class);
						albumAttributeValue.setAlbumId(albumId);
						return albumAttributeValue;
					}).collect(Collectors.toList());


			albumAttributeValueService.saveBatch(albumAttributeValueList);
		}


		//存储状态
		//3.初始化专辑统计信息
		this.saveAlbumInfoStat(albumId, ALBUM_STAT_PLAY, 0);
		this.saveAlbumInfoStat(albumId, ALBUM_STAT_SUBSCRIBE, 0);
		this.saveAlbumInfoStat(albumId, ALBUM_STAT_BUY, 0);
		this.saveAlbumInfoStat(albumId, ALBUM_STAT_COMMENT, 0);

		//TODO 对专辑内容（标题、简介等）进行审核
		String text = albumInfo.getAlbumTitle() + albumInfo.getAlbumIntro();
		String suggestion = auditService.auditText(text);
		if ("pass".equals(suggestion)) {
			albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
			//采用rabbitMQ的方案
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumId);

		} else if ("block".equals(suggestion)) {
			albumInfo.setStatus(SystemConstant.ALBUM_STATUS_NO_PASS);
		} else if ("review".equals(suggestion)) {
			albumInfo.setStatus(SystemConstant.ALBUM_STATUS_ARTIFICIAL);
		}
		albumInfoMapper.updateById(albumInfo);

	}


	/**
	 * 保存专辑统计信息
	 *
	 * @param albumId  专辑ID
	 * @param statType 统计类型
	 * @param statNum  统计数值 0401-播放量 0402-订阅量 0403-购买量 0403-评论数'
	 */
	@Override
	public void saveAlbumInfoStat(Long albumId, String statType, int statNum) {

		AlbumStat albumStat = new AlbumStat();
		albumStat.setAlbumId(albumId);
		albumStat.setStatType(statType);
		albumStat.setStatNum(statNum);
		albumStatMapper.insert(albumStat);
	}



	/**
	 *
	 * 获取当前用户全部专辑列表
	 * @return
	 */
	@Override
	public List<AlbumInfo> getUserAllAlbumList(Long userId) {
		//1.构建查询条件QueryWrapper对象
		LambdaQueryWrapper<AlbumInfo> queryWrapper = new LambdaQueryWrapper<>();
		//1.1 查询条件
		queryWrapper.eq(AlbumInfo::getUserId, userId);
		queryWrapper.eq(AlbumInfo::getStatus, ALBUM_STATUS_PASS);

		//1.3 限制记录数
		queryWrapper.last("LIMIT 200");
		//1.4 指定查询列
		queryWrapper.select(AlbumInfo::getId, AlbumInfo::getAlbumTitle);
		//2.执行列表查询
		return albumInfoMapper.selectList(queryWrapper);
	}


	/**
	 * \
	 * 分页条件查询当前登录用户发布专辑
	 *
	 * @param page
	 * @param limit
	 * @param albumInfoQuery
	 * @return
	 */
	@Override
	public IPage<AlbumListVo> findUserAlbumPage(IPage<AlbumListVo> pageInfo, AlbumInfoQuery albumInfoQuery) {

		IPage<AlbumListVo> page = albumInfoMapper.findUserAlbumPage(pageInfo,albumInfoQuery);

		return page;
	}

	/**
	 * 删除专辑（包括标签关系、统计数值）
	 *
	 * @param id
	 * @return
	 */
	@Override
	public void removeAlbumInfo(Long id) {
		//不光需要删除专辑表本身,与它关联的表也需要一并删除
		//1.根据专辑ID查询声音表判断该专辑下是否关联声音 如果存在 不允许删除
		LambdaQueryWrapper<TrackInfo> trackInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
		trackInfoLambdaQueryWrapper.eq(TrackInfo::getAlbumId,id);
		Long count = trackInfoMapper.selectCount(trackInfoLambdaQueryWrapper);

		if (count > 0 ){
			throw new GuiguException(500,"该专辑下存在关联声音");
		}

		//然后执行删除代码
		albumInfoMapper.deleteById(id);

		LambdaQueryWrapper<AlbumAttributeValue> albumAttributeValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
		albumAttributeValueLambdaQueryWrapper.eq(AlbumAttributeValue::getAlbumId,id);
		albumAttributeValueMapper.delete(albumAttributeValueLambdaQueryWrapper);

		LambdaQueryWrapper<AlbumStat> albumStatLambdaQueryWrapper = new LambdaQueryWrapper<>();
		albumStatLambdaQueryWrapper.eq(AlbumStat::getAlbumId,id);
		albumStatMapper.delete(albumStatLambdaQueryWrapper);

		//5.TODO 基于MQ删除存在Elasticsearch（全文搜索引擎）中数据
		rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,id);
	}


	/**
	 * 主要用来修改专辑时回显数据d
	 * @param id
	 * @return
	 */
	@Override
	@GuiGuCache(prefix = RedisConstant.ALBUM_INFO_PREFIX)
	public AlbumInfo getAlbumInfo(Long id) {

		AlbumInfo albumInfo = albumInfoMapper.selectById(id);


		List<AlbumAttributeValue> albumAttributeValueList = new ArrayList<>();

		LambdaQueryWrapper<AlbumAttributeValue> albumAttributeValueLambdaQueryWrapper = new LambdaQueryWrapper<>();

		albumAttributeValueLambdaQueryWrapper.eq(AlbumAttributeValue::getAlbumId,id);

		List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueMapper.selectList(albumAttributeValueLambdaQueryWrapper);

		albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);


		return albumInfo;
	}


	/**
	 * 修改专辑功能接口
	 * @param id
	 * @param albumInfoVo
	 * @return
	 */
	@Override
	public void updateAlbumInfo(Long id, AlbumInfoVo albumInfoVo) {

		//1.更新专辑信息 状态：未审核
		AlbumInfo albumInfo = BeanUtil.copyProperties(albumInfoVo, AlbumInfo.class);

		albumInfo.setId(id);
		albumInfo.setStatus(ALBUM_STATUS_NO_PASS);

		albumInfoMapper.updateById(albumInfo);

		//2.更新专辑标签关系
		//2.1 根据专辑ID删除原有标签关系
		LambdaQueryWrapper<AlbumAttributeValue> albumAttributeValueLambdaQueryWrapper = new LambdaQueryWrapper<>();

		albumAttributeValueLambdaQueryWrapper.eq(AlbumAttributeValue::getAlbumId,id);

		albumAttributeValueMapper.delete(albumAttributeValueLambdaQueryWrapper);

		//2.2 从VO中获取提交专辑标签关系集合 再次批量保存

		List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();

		List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueVoList.stream().map(vo -> {
			AlbumAttributeValue albumAttributeValue = BeanUtil.copyProperties(vo, AlbumAttributeValue.class);
			albumAttributeValue.setAlbumId(id);
			return albumAttributeValue;
		}).collect(Collectors.toList());


		//2.3为专辑标签关联专辑ID，"批量"新增专辑标签关系
		albumAttributeValueService.saveBatch(albumAttributeValueList);

		//3.TODO 再次对内容进行审核

		String text = albumInfo.getAlbumTitle() + albumInfo.getAlbumIntro();
		String suggestion = auditService.auditText(text);
		if ("pass".equals(suggestion)) {
			albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
			//将过深的专辑存到索引库中
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,id);
		} else if ("block".equals(suggestion)) {
			albumInfo.setStatus(SystemConstant.ALBUM_STATUS_NO_PASS);
		} else if ("review".equals(suggestion)) {
			albumInfo.setStatus(SystemConstant.ALBUM_STATUS_ARTIFICIAL);
		}
		albumInfoMapper.updateById(albumInfo);

	}


	/**
	 * 根据专辑ID查询专辑统计信息
	 * @param albumId
	 * @return
	 */
	@Override
	@GuiGuCache(prefix = RedisConstant.ALBUM_INFO_PREFIX + "stat:")
	public AlbumStatVo getAlbumStatVo(Long albumId) {

		//根据id查询
		AlbumStatVo albumStatVo = albumStatMapper.getAlbumStatVo(albumId);


		return albumStatVo;
	}

	@Override
	public List<Long> findAlbumIdListByStatus(String albumStatusPass) {

		LambdaQueryWrapper<AlbumInfo> wrapper = new LambdaQueryWrapper<>();

		wrapper.eq(AlbumInfo::getStatus,albumStatusPass);

		List<AlbumInfo> albumInfos = albumInfoMapper.selectList(wrapper);

		List<Long> albumIdList = albumInfos.stream().map(info -> info.getId()).collect(Collectors.toList());

		return albumIdList;
	}

}
